package com.wing.member.controller.admin;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wing.common.utils.JsonResult;
import com.wing.common.utils.LocalDateTimeUtils;
import com.wing.common.utils.PageResult;
import com.wing.member.model.entity.Member;
import com.wing.member.service.MemberService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.Map;

/**
 * @author
 */
@Api(value = "Admin-用户管理", tags = "#/member/member")
@RestController("memberController")
@RequestMapping("member/admin/member")
public class MemberController {

    @Autowired
    private MemberService memberService;

    @ApiOperation(value = "查询所有用户信息", notes = "搜索")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "第几页", defaultValue = "1", dataType = "Integer", paramType = "query")
            , @ApiImplicitParam(name = "limit", value = "每页多少条", defaultValue = "10", dataType = "Integer", paramType = "query")
            , @ApiImplicitParam(name = "sort", value = "排序字段名", defaultValue = "create_time", dataType = "String", paramType = "query")
            , @ApiImplicitParam(name = "order", value = "排序规则(asc:正序, desc:倒序)", defaultValue = "asc", dataType = "String", paramType = "query")
            , @ApiImplicitParam(name = "username", value = "用户名", dataType = "String", paramType = "query")
            , @ApiImplicitParam(name = "memberRankName", value = "用户等级", dataType = "String", paramType = "query")
            , @ApiImplicitParam(name = "parentUsername", value = "父级用户名", dataType = "String", paramType = "query")
    })
    @GetMapping("/list")
    public PageResult<Member> list(
            Integer page
            , Integer limit
            , String sort
            , String order
            , String username
            , String memberRankName
            , String parentUsername
    ) {

        Page<Member> pg = new Page<>(page, limit);
        Map<String, Object> params = new HashMap<>();

        //排序
        if (StringUtils.isNotBlank(sort) && StringUtils.isNotBlank(order)) {
            params.put("sort", StrUtil.toUnderlineCase(sort));
            params.put("order", StrUtil.toUnderlineCase(order));
        }

        //搜索
        if (StringUtils.isNotBlank(username)) {
            params.put("username", username);
        }
        if (StringUtils.isNotBlank(memberRankName)) {
            params.put("memberRankName", memberRankName);
        }
        if (StringUtils.isNotBlank(parentUsername)) {
            params.put("parentUsername", parentUsername);
        }

        IPage<Member> list = memberService.pageList(pg, params);
        return new PageResult<>(list.getRecords(), list.getTotal());
    }

    @ApiOperation(value = "修改用户信息", notes = "修改")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "member", value = "用户信息", required = true, dataType = "Member", paramType = "form"),
            @ApiImplicitParam(name = "access_token", value = "令牌", required = true, dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "password", value = "登录密码", dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "newPayPassword", value = "支付密码", dataType = "String", paramType = "form")
    })
    @PutMapping("/update")
    public JsonResult update(Long id, String email, String password, String newPayPassword) {
        if (memberService.updatePassword(id, email, password, newPayPassword)) {
            return JsonResult.success("修改成功！");
        }
        return JsonResult.fail("修改失败！");
    }

    @ApiOperation(value = "查看用户统计")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "类型", defaultValue = "0", dataType = "Integer", paramType = "query")
    })
    @GetMapping("/memberStatistic")
    public JsonResult count(@RequestParam(value = "type", defaultValue = "0", required = false) Integer type) {
        JSONObject data = new JSONObject();
        JSONArray dateArray = new JSONArray();
        JSONArray dataArray = new JSONArray();
        type = type == null ? 0 : type;
        LocalDateTime nowTime = LocalDateTime.now();
        switch (type) {
            //最近一周
            case 0:
                for (int i = -6; i <= 0; i++) {
                    LocalDateTime time = LocalDateTimeUtils.plus(nowTime, i, ChronoUnit.DAYS);
                    int count = memberService.count(new QueryWrapper<Member>().ge("create_time", LocalDateTimeUtils.getDayStart(time)).le("create_time", LocalDateTimeUtils.getDayEnd(time)));
                    dataArray.add(count);
                    dateArray.add(LocalDateTimeUtils.formatTime(time, "yyyy-MM-dd"));
                }
                break;
            //最近一个月
            case 1:
                for (int i = -29; i <= 0; i++) {
                    LocalDateTime time = LocalDateTimeUtils.plus(nowTime, i, ChronoUnit.DAYS);
                    int count = memberService.count(new QueryWrapper<Member>().ge("create_time", LocalDateTimeUtils.getDayStart(time)).le("create_time", LocalDateTimeUtils.getDayEnd(time)));
                    dataArray.add(count);
                    dateArray.add(LocalDateTimeUtils.formatTime(time, "yyyy-MM-dd"));
                }
                break;
            //最近三个月
            case 2:
                for (int i = -89; i <= 0; i++) {
                    LocalDateTime time = LocalDateTimeUtils.plus(nowTime, i, ChronoUnit.DAYS);
                    int count = memberService.count(new QueryWrapper<Member>().ge("create_time", LocalDateTimeUtils.getDayStart(time)).le("create_time", LocalDateTimeUtils.getDayEnd(time)));
                    dataArray.add(count);
                    dateArray.add(LocalDateTimeUtils.formatTime(time, "yyyy-MM-dd"));
                }
                break;
            //最近半年
            case 3:
                for (int i = -182; i <= 0; i++) {
                    LocalDateTime time = LocalDateTimeUtils.plus(nowTime, i, ChronoUnit.DAYS);
                    int count = memberService.count(new QueryWrapper<Member>().ge("create_time", LocalDateTimeUtils.getDayStart(time)).le("create_time", LocalDateTimeUtils.getDayEnd(time)));
                    dataArray.add(count);
                    dateArray.add(LocalDateTimeUtils.formatTime(time, "yyyy-MM-dd"));
                }
                break;
            //最近一年
            case 4:
                for (int i = -364; i <= 0; i++) {
                    LocalDateTime time = LocalDateTimeUtils.plus(nowTime, i, ChronoUnit.DAYS);
                    int count = memberService.count(new QueryWrapper<Member>().ge("create_time", LocalDateTimeUtils.getDayStart(time)).le("create_time", LocalDateTimeUtils.getDayEnd(time)));
                    dataArray.add(count);
                    dateArray.add(LocalDateTimeUtils.formatTime(time, "yyyy-MM-dd"));
                }
                break;
            default:
                //最近一周
                for (int i = -7; i < 0; i++) {
                    LocalDateTime time = LocalDateTimeUtils.plus(nowTime, i, ChronoUnit.DAYS);
                    int count = memberService.count(new QueryWrapper<Member>().ge("create_time", LocalDateTimeUtils.getDayStart(time)).le("create_time", LocalDateTimeUtils.getDayEnd(time)));
                    dataArray.add(count);
                    dateArray.add(LocalDateTimeUtils.formatTime(time, "yyyy-MM-dd"));
                }
                break;
        }
        data.put("totalCount", memberService.count());
        data.put("dataArray", dataArray);
        data.put("dateArray", dateArray);
        return JsonResult.success(data);
    }

}
